package interfaceTest;

class Money implements Cloneable {
    int CNY = 100;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Man implements Cloneable {
    public int age = 18;
    public Money money = new Money();

    @Override
    //不同包中 被protected 修饰的方法应用super调用
    protected Object clone() throws CloneNotSupportedException {
        //先浅拷贝出来一个实例对象 赋给tmp
        Man tmp = (Man) super.clone();
        //再更改这个浅拷贝出来的 tmp 的 money 引用 为当前(this) 对象中的 money 的深拷贝
        tmp.money=(Money)this.money.clone();
        //返回tmp 可以不强转 因为会发生向上转型
        return tmp;
        //由于 clone 被 native 修饰了意味着该方法属于 底层代码(C/C++实现) 故我们无法直接查看
    }

    @Override
    public String toString() {
        return "Man{" +
                "age=" + age +
                ",CNY=" + money.CNY +
                '}';
    }
}

public class Test4 {
    //Cloneable 接口和深浅拷贝

    public static void main(String[] args) throws CloneNotSupportedException {
        //当我给Man中新增一个Money 类后
        Man man1 = new Man();
        Man man2 = (Man) man1.clone();
        System.out.println("Init: " + man1 + " " + man2);
        man2.money.CNY = 666;
        System.out.println("change: " + man1 + " " + man2);
        //Init: Man{age=18,CNY=100} Man{age=18,CNY=100}
        //change: Man{age=18,CNY=666} Man{age=18,CNY=666}

        //此时我就改了 man2 的 money 但为啥 man1 的 money 也跟着改了呢?
        //因为发生了浅拷贝 那该如何变成深拷贝呢?
        //在 Money 类中重写 clone 并在 Man 类中的 clone 中 调用它

        //改为之后就 就是运行出了我们希望的结果了
        //Init: Man{age=18,CNY=100} Man{age=18,CNY=100}
        //change: Man{age=18,CNY=100} Man{age=18,CNY=666}
    }

    //                                     异常(下回分解)
    public static void main1(String[] args) throws CloneNotSupportedException {
        Man man1 = new Man();
        Man man2 = (Man) man1.clone();//返回值为父类 Object 向下转型 故需要 强转
        man2.age = 66;
        System.out.println(man1);
        System.out.println(man2);
        //Man{age=18}
        //Man{age=66}
    }
}
